﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Helpers;
using SilverPOP.Data.Process.BLL;
using SilverPOP.Data.Process.Entity;
using Utilities;
using SilverPOP.Library.Helpers;
using SilverPOP.Library.BusinessEntities;

namespace SilverPOP.Data.Process.OperationUnit
{
    public class SilverPOPAggregateReportProcess : DataAndSchemaProcess
    {
        #region Fields
         DateTime _trackingStartTime, _trackingEndTime,_currentDate;
         List<CampaignWithBlast> campaignWithBlast = null;
         List<SilverPOPReportIDInfo> reportSilverPOPBulkInfo = new List<SilverPOPReportIDInfo>();
         List<ReportQueue> _reportQueue = new List<ReportQueue>();
         bool _isUniqueReport = false;

        #endregion

        #region Constructor

         public SilverPOPAggregateReportProcess(TaskListEntity task)
         {
            
             DAL.DAL.SetConnectionString(task.ServerName, task.DatabaseName, task.Username, task.Password);
             SilverPOPAggregateReportProcessInit(task.CampaignId);
         }

         private void SilverPOPAggregateReportProcessInit(long campaignId,bool isUniqueReport=default(bool),List<ReportQueue> reportQueue = default(List<ReportQueue>))
         {
           
             this.campaignId = campaignId;
             this.CreateFolder(ConfigHelpers.LocalSilverPOPSummaryDirectoryName);
             this._trackingStartTime = ConfigHelpers.TrackingStartTime;
             this._trackingEndTime = DateTime.Now;
             this._isUniqueReport = isUniqueReport;
             this._reportQueue = reportQueue == default(List<ReportQueue>) ? null : reportQueue;
         }
         #endregion

        public override void ExecuteOperation()
        {
            try
            {
                SilverPOPAggregateReportBLL.ProcessSilverPopAggregateSummary(this.campaignId);
                Console.WriteLine("Inserting SilverPOP Summary Data In Database Completed.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Inserting SilverPOP Summary Data In Database Completed.");

               ////////////////////////////////////////////////////////////
                //this._currentDate = DateTime.Now;
               // campaignWithBlast = SilverPOPAggregateReportBLL.GetActiveCampaignWithItsBlast(this.campaignId);
                //if (this._isUniqueReport)
                //{
                //    //This block will be executed after completing the SilverPOP Raw Report Process
                //    //Execute operation is initialted from the SilverPOP Raw Report process
                //    DoSilverPOPUniqueTrackingDataProcess();
                //}
                //else
                //{
                //    this.processStartingTime = DateTime.Now.TimeOfDay;
                //    DoSilverPOPAggregateTrackingDataProcess();
                //    this.CalculateTotalProcessingTime();
                //}
                /////////////////////////////////////////////////////////////
                
            }
            catch (Exception ex)
            {
                this.LogError(ex);
            }
        }

        #region SilverPOP Aggregate Tracking Report  Process
        private void DoSilverPOPAggregateTrackingDataProcess()
        {
            Console.WriteLine("SilverPOP Aggregate Summary Data Generation Started.");
            FileWriter.WriteToFile(this.successFileNameWithPath, "SilverPOP Aggregate Summary Data Generation Started.");


            GetSilverPOPReportIDs();
            GetSilverPOPAggregateTrackingData();

            Console.WriteLine("SilverPOP Aggregate Summary Data Generation Completed.");
            FileWriter.WriteToFile(this.successFileNameWithPath, "SilverPOP Aggregate Summary Data Generation Completed.");
        }
        #endregion

        #region SilverPOP Unique Tracking Report Process
        private void DoSilverPOPUniqueTrackingDataProcess()
        {
            Console.WriteLine("SilverPOP Unique Report Data Generation Started.");
            FileWriter.WriteToFile(this.successFileNameWithPath, "SilverPOP Unique Report Data Generation Started.");


            GetSilverPOPReportIDs();
            GetSilverPOPUniqueTrackingData();

            Console.WriteLine("SilverPOP Unique Report Data Generation Completed.");
            FileWriter.WriteToFile(this.successFileNameWithPath, "SilverPOP Unique Report Data Generation Completed.");
        }
        #endregion

        #region Get SilverPOP Report ID Related Methods
        private void GetSilverPOPReportIDs()
        {
            Console.WriteLine("SilverPOP Report ID Fetching Started ...");
            FileWriter.WriteToFile(this.successFileNameWithPath,"SilverPOP Report ID Fetching Started ...");
            
            GetSilverPOPReportIDsFromDB();

            if (reportSilverPOPBulkInfo != null && reportSilverPOPBulkInfo.Count > 0)
            {
                //If SilverPOP report ID not found in database then get it from SilverPOP and save it
                // our database

                bool haveNotAllReportIDs = reportSilverPOPBulkInfo.Exists(x => x.ReportId <= 0);

                if (haveNotAllReportIDs)
                {
                    //Get SilverPOP report id from SilverPOP
                    reportSilverPOPBulkInfo = SilverPopHelpers.GetReportIDForMailing(this.InstanceSilverPOPAccount, reportSilverPOPBulkInfo, _trackingStartTime, _trackingEndTime);
                }

                if (reportSilverPOPBulkInfo != null)
                {
                    foreach (SilverPOPReportIDInfo silverPOPReportIdInfo in reportSilverPOPBulkInfo)
                    {
                            //If the  Report Id is just getting from SilverPOP then save it in our database 
                        if (silverPOPReportIdInfo.JustGetFromSilverPOP)
                        {
                            SilverPOPAggregateReportBLL.UpdateSilverPOPReportIDInDatabase(silverPOPReportIdInfo.BlastId, silverPOPReportIdInfo.MailingId, silverPOPReportIdInfo.ReportId,this._currentDate);
                        }

                            Console.WriteLine("For BlastID: " + silverPOPReportIdInfo.BlastId + " SegmentID:"+silverPOPReportIdInfo.SegmentId+" MailingID:"+silverPOPReportIdInfo.MailingId +" SilverPOP ReportID is: " + silverPOPReportIdInfo.ReportId);
                            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID: " + silverPOPReportIdInfo.BlastId + " SegmentID:" + silverPOPReportIdInfo.SegmentId + " MailingID:" + silverPOPReportIdInfo.MailingId + " SilverPOP ReportID is: " + silverPOPReportIdInfo.ReportId);
                    }
                 }
             }

            Console.WriteLine("SilverPOP Report ID Fetching Completed.");
            FileWriter.WriteToFile(this.successFileNameWithPath, "SilverPOP Report ID Fetching Completed.");

        }

        private void GetSilverPOPReportIDsFromDB()
        {

            if (campaignWithBlast != null)
            {
                foreach (CampaignWithBlast campaignBlast in campaignWithBlast)
                {
                    //for each campaign get its campaigns Blast related info
                    foreach (long blastId in campaignBlast.BlastIDs)
                    {
                       List<SilverPOPReportIDInfo> reportInfo= SilverPOPAggregateReportBLL.GetSilverPOPActiveReportIDs(blastId);

                       if (reportInfo != null && reportInfo.Count > 0)
                       {
                           reportSilverPOPBulkInfo.AddRange(reportInfo);
                       }
                    }
                }

            }//end if
        }

       #endregion

        #region Get SilverPOP Unique Tracking Data

        private void GetSilverPOPUniqueTrackingData()
        {
            if (reportSilverPOPBulkInfo != null && reportSilverPOPBulkInfo.Count > 0 && this._reportQueue != null)
            {

                List<SilverPOPReportUniqueCount> uniqueCountList = new List<SilverPOPReportUniqueCount>();

                foreach (ReportQueue rptQueue in this._reportQueue)
                {
                    SilverPOPReportIDInfo reportInfo = reportSilverPOPBulkInfo.Where(x => (x.BlastId == rptQueue.BlastId) && (x.MailingId == rptQueue.MailingId)).FirstOrDefault();

                    if (reportInfo != null)
                    {
                        SilverPOPReportUniqueCount uniqueCount = new SilverPOPReportUniqueCount(rptQueue.BlastId, rptQueue.MailingId, reportInfo.SegmentId, reportInfo.ReportId);
                        uniqueCountList.Add(uniqueCount);
                    }

                }
                Console.WriteLine("Unique Event Type Data Count Process From SilverPOP Started.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Unique Event Type Data Count Process From SilverPOP Started.");


                List<SummaryReport> summaryReportList = SilverPopHelpers.GetUniqueTrackingForMailing(this.InstanceSilverPOPAccount, uniqueCountList);

                if (summaryReportList != null)
                {
                    DisplayAndInsertDataInDatabase(summaryReportList);
                }

                Console.WriteLine("Unique Event Type Data Count Process From SilverPOP Completed.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Unique Event Type Data Count Process From SilverPOP Completed.");

            }
            else
            {
                throw new Exception("SilverPOP reportId not found.");
            }
        }

        private void DisplayAndInsertDataInDatabase(List<SummaryReport> summaryReportList)
        {

            foreach (SummaryReport report in summaryReportList)
            {
                DisplayAndWriteUniqueReport(report);

                //==== SAVE IN DB
                Console.WriteLine("Event Type Count Data Insertion in Database Started For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID);
                FileWriter.WriteToFile(this.successFileNameWithPath, "Event Type Count Data Insertion in Database Started For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID);

                SilverPOPAggregateReportBLL.InsertUniqueEventTypeCount(report);

                Console.WriteLine("Event Type Count Data Insertion in Database Completed.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Event Type Count Data Insertion in Database Completed.");
            }
        }

        private void DisplayAndWriteUniqueReport(SummaryReport report)
        {
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Unique Open Count is:" + report.UniqueOpen);
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Unique Click Count is:" + report.UniqueClick);

            Console.WriteLine();
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Unique Open Count is:" + report.UniqueOpen);
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Unique Click Count is:" + report.UniqueClick);

            FileWriter.WriteToFile(this.successFileNameWithPath, "");
        }


        #endregion

        #region Get SilverPOP Aggregate Tracking Data

        public void GetSilverPOPAggregateTrackingData()
        {
            if (reportSilverPOPBulkInfo != null && reportSilverPOPBulkInfo.Count > 0)
            {
            
                Console.WriteLine("Getting Summary Data From SilverPOP Started.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Getting Summary Data From SilverPOP Started.");

                //Get distinct blast Id list
                List<long> blastIdList = reportSilverPOPBulkInfo.Select(x => x.BlastId).Distinct().ToList();

                List<SummaryReport> summaryReportList =  SilverPopHelpers.GetAggregateTrackingForMailing(this.InstanceSilverPOPAccount, reportSilverPOPBulkInfo);
                  
                Console.WriteLine("Getting Summary Data From SilverPOP Completed.");
                FileWriter.WriteToFile(this.successFileNameWithPath, "Getting Summary Data From SilverPOP Completed.");

                  if (summaryReportList != null)
                  {
                      
                      //====For a blastID there may be several segments, so we sum all segments report for a blastID and save it in database====
                      foreach (long blastId in blastIdList)
                      {
                          SummaryReport summationOfSummaryReport = new SummaryReport();
                          List<SummaryReport> summarySubReport = summaryReportList.FindAll(x => x.BlastID == blastId).ToList();

                          //====For a blastID there may be several segments, so we sum all segments report for a blastID and save it in database====
                          foreach (SummaryReport report in summarySubReport)
                          {
                              summationOfSummaryReport.BlastID = report.BlastID;
                              summationOfSummaryReport.SentCount  += report.SentCount;
                              summationOfSummaryReport.BouncedCount  += report.BouncedCount;
                              summationOfSummaryReport.OpenedCount  += report.OpenedCount;
                              summationOfSummaryReport.ClickedCount += report.ClickedCount;
                              summationOfSummaryReport.OptOutCount += report.OptOutCount;

                              DisplayAndWriteAggregateReport(report);
                          }

                          Console.WriteLine("Inserting SilverPOP Summary Data In Database For Blast ID: " + summationOfSummaryReport.BlastID);
                          FileWriter.WriteToFile(this.successFileNameWithPath, "Inserting SilverPOP Summary Data In Database For Blast ID: " + summationOfSummaryReport.BlastID);

                          //Insert data in database
                          SilverPOPAggregateReportBLL.InsertSilverPOPSummaryDataInDatabase(summationOfSummaryReport, DateTime.Now);
                      }
                      Console.WriteLine("Inserting SilverPOP Summary Data In Database Completed.");
                      FileWriter.WriteToFile(this.successFileNameWithPath, "Inserting SilverPOP Summary Data In Database Completed.");
                  }
            }
            else
            {
                throw new Exception("SilverPOP reportId not found.");
            }

        }

        private void DisplayAndWriteAggregateReport(SummaryReport report)
        {
            Console.WriteLine("For BlastID:"+report.BlastID+" SegmentID:"+report.SegmentID+" MailingID: "+report.MailingID+" Sent Count is:"+report.SentCount);
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Bounced Count is:" + report.BouncedCount);
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Opened Count is:" + report.OpenedCount);
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Clicked Count is:" + report.ClickedCount);
            Console.WriteLine("For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Opt out Count is:" + report.OptOutCount);
            Console.WriteLine();
            FileWriter.WriteToFile(this.successFileNameWithPath,"For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Sent Count is:" + report.SentCount);
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Bounced Count is:" + report.BouncedCount);
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Opened Count is:" + report.OpenedCount);
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Clicked Count is:" + report.ClickedCount);
            FileWriter.WriteToFile(this.successFileNameWithPath, "For BlastID:" + report.BlastID + " SegmentID:" + report.SegmentID + " MailingID: " + report.MailingID + " Opt out Count is:" + report.OptOutCount);
            FileWriter.WriteToFile(this.successFileNameWithPath, "");
        }

        #endregion


        



    }//end class
}
